/**
 * QueueBase
 * methods:isEmpty,size,clear,toString
 */
export class QueueBase {
  protected items: Map<number, any>;
  protected count: number;
  protected lowestCount: number;

  public constructor(...initials: any[]) {
    this.count = 0;
    this.lowestCount = 0;
    this.items = new Map();

    initials.forEach((item, index) => {
      this.items.set(index, item);
      this.count = index + 1;
    });
  }

  public isEmpty() {
    return (this.count - this.lowestCount) === 0;
  }

  public size() {
    return this.count - this.lowestCount;
  }

  public clear() {
    this.items = new Map();
    this.lowestCount = 0;
    this.count = 0;
  }

  public toString() {
    if (this.isEmpty()) {
      return '';
    }

    let str = `${this.items.get(this.lowestCount)}`;
    for (let i = this.lowestCount + 1; i < this.count; i++) {
      str = `${str},${this.items.get(i)}`;
    }
    return str;
  }

  protected peakFront() {
    if (this.isEmpty()) {
      return undefined;
    }
    return this.items.get(this.lowestCount);
  }

  protected peakBack() {
    if (this.isEmpty()) {
      return undefined;
    }
    return this.items.get(this.count - 1);
  }

  protected addBack(element) {
    this.items.set(this.count, element);
    this.count++;
  }

  protected removeFront() {
    if (this.isEmpty()) {
      return undefined;
    }
    
    const result = this.items.get(this.lowestCount);
    this.items.delete(this.lowestCount);
    this.lowestCount++;

    return result;
  }

  protected removeBack() {
    if (this.isEmpty()) {
      return undefined;
    }

    const result = this.items.get(this.count - 1);
    this.items.delete(this.count - 1);
    this.count--;
    return result;
  }
}